package mainClient;


import interaction.BDConnection;
import interaction.BDDisconnect;
import interaction.SendBD;
import interaction.SendRes;


import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

import utils.StreamUtils;

public class TcpClient extends DefaultClient
{  
  private static final int TIMEOUT = 5000;
  private String m_ip;
  private int m_port;  
  private boolean m_isConnected = false;
  private Socket m_socket; 
  private java.io.InputStream m_input;
  private java.io.OutputStream m_output;
  
  public TcpClient(int port, String ip, int selfPort)
  {
    m_port = port;
    m_ip = ip;        
  }
  
  @Override
  public boolean connect()
  {
    if(m_isConnected == true)
    {
      System.out.println("Попытка повторного соединения");
      return true;
    }
    
    try
    {
      m_socket = new Socket(m_ip, m_port);           
    }
    catch (UnknownHostException e)
    {   
      System.out.println("Ошибка создания TCP сокета, сервер не найден");      
      return false;      
    }
    catch (IOException e)
    {
      System.out.println("Ошибка создания TCP сокета");      
      return false;
    }
    
    try
    {
      m_socket.setSoTimeout(TIMEOUT);
    }
    catch (SocketException e)
    {            
      System.out.println("Ошибка установки таймаута");
      return false;
    }    
       
    System.out.println("Создан TCP сокет");
    
    if(initStreams() == false)
      return false;
    
    BDConnection queryConn = new BDConnection();    
      
    try
    {          
      if(StreamUtils.fillStream(m_output, queryConn) == true)      
        System.out.println("Передан запрос на регистрацию " + m_socket.getInetAddress().toString());
      else
        System.out.println("Ошибка передачи данных серверу " + m_socket.getInetAddress().toString());
      
      Object obj = StreamUtils.getStreamObject(m_input);
      
      if(obj == null)
      {
        m_socket.close();
        return false;
      }
      
      if(obj instanceof BDConnection)
      {
        m_id = ((BDConnection)obj).m_clientId; 
        System.out.println("Принят идентификатор клиента " + m_id.toString());
        m_isConnected = true;
      }          
      else
        System.out.println("Передана необрабатываемая логика, ожидался идентификатор клиента");
    }
    catch (IOException e)
    {      
      System.out.println("Ошибка посылки данных через сокет");
    }       
    
    return m_isConnected;
  }

  private boolean initStreams()
  {
    try
    {
      m_input = m_socket.getInputStream();
    }
    catch (IOException e)
    {
      System.out.println("Ошибка получения входного потока у принятого клиента");
      return false;
    }
    
    try
    {
      m_output = m_socket.getOutputStream();
    }
    catch (IOException e)
    {
      System.out.println("Ошибка получения выходного потока у принятого клиента");
      return false;
    }
    
    return true;
  }
  
  @Override
  public boolean disconnect()
  {
    BDDisconnect disconn = new BDDisconnect();
    
    if(m_isConnected == false)
    {
      System.out.println("Попытка повторного отключения");
      return true;
    }

    disconn.m_clientId = m_id;        
    
    if(StreamUtils.fillStream(m_output, disconn) == true)
      System.out.println("Передан запрос на отключение " + m_socket.getInetAddress().toString());
    else
      System.out.println("Сервер уже закрыл соединение " + m_socket.getInetAddress().toString());
    
    m_isConnected = false;
   
    return true;
  }

@Override
public final String SendBDR() {
	
	SendBD mess = new SendBD();
	String result = new String("");
	
	if(m_isConnected == false)
    {
      System.out.println("Нет соединения");
      return result;
    }
	
	mess.m_clientId=m_id;
	//mess.par1 = "";
	//mess.par2 = "";
	
	if(StreamUtils.fillStream(m_output, mess) == true)
	      System.out.println("Передан запрос");
	    else
	    	System.out.println("Ошибка передачи данных серверу " + m_socket.getInetAddress().toString());
	
	Object obj = StreamUtils.getStreamObject(m_input);

    if(obj == null)
      return null;

    if(obj instanceof SendRes)
    {
      result = ((SendRes)obj).res;
      System.out.println("Получен ответ на запрос от " + m_socket.getInetAddress().toString());        
    }          
    else
    	System.out.println("Передана необрабатываемая логика");

        
    return result;    

	
}

}
